package realization;

import interfaces.SingleList;

import java.util.Iterator;

public class LinkedList<T> implements SingleList<T>{

    private Node<T> beginList;
    private Node<T> endList;
    private int size;

    @Override
    public void insert(T element) {
        Node toInsert = new Node<T>(element,null);
        if(endList == null)
            endList = toInsert;
        else {
            endList.nextNode = toInsert;
            endList = endList.nextNode;
        }
        if(beginList == null)
            beginList = endList;
        ++size;
    }

    @Override
    public boolean delete(T element) {
        Node currentElement = beginList;
        if(currentElement == null)
            return false;
        if(currentElement.element.equals(element)){
            beginList = beginList.nextNode;
            --size;
            return true;
        }
        while(currentElement.nextNode != null){
            if(currentElement.nextNode.element.equals(element)){
                if(endList == currentElement.nextNode)
                    endList = currentElement;
                currentElement.nextNode = currentElement.nextNode.nextNode;
                --size;
                return true;
            }
            currentElement = currentElement.nextNode;
        }
        return false;
    }

    @Override
    public boolean isExist(T element) {
        Node currentNode = beginList;
        while (currentNode!=null){
            if(currentNode.element.equals(element))
                return true;
            currentNode = currentNode.nextNode;
        }
        return false;
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public void deleteAll() {
        beginList = null;
        endList = null;
        size = 0;
    }

    @Override
    public Iterator<T> iterator() {
        return new SingleListIterator();
    }
    public class SingleListIterator implements Iterator{

        Node<T> currentNode = beginList;

        @Override
        public boolean hasNext() {
            return currentNode == null?false:true;
        }

        @Override
        public T next() {
            T toReturnElement = currentNode.element;
            currentNode = currentNode.nextNode;
            return toReturnElement;
        }

        @Override
        public void remove() {
            delete(currentNode.element);
        }
    }
    private class Node<T>{
        public T element;
        public Node nextNode;

        public Node(T element, Node nextNode){
            this.element = element;
            this.nextNode = nextNode;
        }
    }
}
